
#include "pch.h"
#include "ExtrudeSkeleton.h"

extern "C" void ExtrudeSkeleton(
    double* polygon2DArray, size_t* polygonCountArray, size_t polygonCount,
    double* angleArray,
    double maximum_height,
    double*& meshArray, int*& faceCount
)
{
    std::vector<Point_2> outerBoundary;
    for (size_t i = 0; i < polygonCountArray[0]; ++i) {
        outerBoundary.emplace_back(polygon2DArray[i * 2], polygon2DArray[i * 2 + 1]);
    }

    Polygon_2 outer(outerBoundary.begin(), outerBoundary.end());
    Polygon_with_holes_2 pwh(outer);
    // ��ӿ�
    size_t offset = polygonCountArray[0];
    for (size_t polyIdx = 1; polyIdx < polygonCount; ++polyIdx) {  // ������һ������Ϊ��������߽�
        std::vector<Point_2> hole;
        for (size_t i = 0; i < polygonCountArray[polyIdx]; ++i) {
            hole.emplace_back(polygon2DArray[(offset + i) * 2], polygon2DArray[(offset + i) * 2 + 1]);
        }
        offset += polygonCountArray[polyIdx] * 2;
        Polygon_2 h(hole.begin(), hole.end());
        pwh.add_hole(h);
    }

	Mesh mesh;
    FT height = FT{ (std::numeric_limits<double>::max)() };
	height = maximum_height;

    std::vector<std::vector<FT>>angles(polygonCount);

    size_t angleIndex = 0;
    for (size_t i = 0; i < polygonCount; ++i) {
        // ��ȡ��ǰ����εı���
        size_t numEdges = polygonCountArray[i];
        // Ϊ��ǰ����δ���һ���Ƕ�������
        std::vector<FT> currentPolygonAngles(numEdges);
        // �� angleArray �и��ƶ�Ӧ�ĽǶ�ֵ
        for (size_t j = 0; j < numEdges; ++j) {
            currentPolygonAngles[j] = angleArray[angleIndex++];
        }
        // ����ǰ����εĽǶ���������ӵ� angles ��
        angles[i] = currentPolygonAngles;
    }


	extrude_skeleton(pwh, mesh, CGAL::parameters::angles(angles).maximum_height(height));

    faceCount =new int(mesh.faces().size());
    std::vector<double> extrudedPolygons;

    for (const auto& face : mesh.faces())
    {
        std::vector<Point_3> vertices;
        for (auto v : CGAL::vertices_around_face(mesh.halfedge(face), mesh))
        {
            const auto& point = mesh.point(v);
            vertices.push_back(point);
        }

        for (const auto& vertex : vertices)
        {
            extrudedPolygons.push_back(vertex.x());
            extrudedPolygons.push_back(vertex.y());
            extrudedPolygons.push_back(vertex.z());
        }
    }

    // Allocate memory for the output arrays
    meshArray = new double[extrudedPolygons.size()];
    std::copy(extrudedPolygons.begin(), extrudedPolygons.end(), meshArray);
}
